import { _decorator, Asset, assetManager, AssetManager, Component, ImageAsset, SpriteFrame, Texture2D } from 'cc';
const { ccclass, property } = _decorator;

export default class ResManager extends Component {
    private static _instance;

    static get instance(): ResManager {
        if (this._instance == null) {
            this._instance = new ResManager();
        }
        return this._instance
    }


    loadedBundle: Map<string, AssetManager.Bundle> = new Map<string, AssetManager.Bundle>()
    loadedAsset: Map<string, any> = new Map<string, any>();


    loadBundle(name: string): Promise<AssetManager.Bundle> {
        return new Promise((resolve, reject) => {
            if (this.loadedBundle.has(name)) {
                resolve(this.loadedBundle.get(name))
                return
            }

            assetManager.loadBundle(name, (err, ab: AssetManager.Bundle) => {
                // assetManager.removeBundle(ab);
                this.loadedBundle.set(name, ab)
                resolve(ab)
            });
        })
    }

    loadAsset<T extends Asset>(ab: AssetManager.Bundle, name: string): Promise<T> {
        return new Promise((resolve, reject) => {
            let url = ab.name + '/' + name
            if (this.loadedAsset.has(url)) {

                resolve(this.loadedAsset.get(url))
                return
            }

            ab.load<T>(name, (err, asset: T) => {

                this.loadedAsset.set(url, asset);
                resolve(asset)
            })
        })
    }

    async loadAssetByUrl<T extends Asset>(url: string) {
        let adName = url.substring(0, url.indexOf('/'))
        let assetName = url.substring(url.indexOf('/') + 1)
        let ab = await this.loadBundle(adName)
        let assert = await this.loadAsset<T>(ab, assetName)
        return assert
    }

    loadRemote(url:string): Promise<SpriteFrame> {
        return new Promise((resolve,reject) => {
            assetManager.loadRemote<ImageAsset>(url, function (err, imageAsset) {
                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                resolve(spriteFrame) 
            });
        })
        
    }

    loadRemoteByUrl<T extends Asset>(url:string): Promise<T>{
        return new Promise((resolve,reject) => {
            assetManager.loadRemote<T>(url, function (err, asset:T) {
                resolve(asset) 
            });
        })
    }


}


